Use FixedAspectRatioImageView to demo auto-enter-pip Video: http://recall/-/aaaaaabFQoRHlzixHdtY/bpKcGg1eoOo5Jz5U6IwBYK Bug: 191310680 Test: manually auto-enter-pip from landscape, see video Change-Id: I30a728331f0ffa48c537be7b2611dba0b2df053a 
diff --git a/samples/ApiDemos/res/layout/picture_in_picture_auto_enter.xml b/samples/ApiDemos/res/layout/picture_in_picture_auto_enter.xml index 09912b5..57f891e 100644 --- a/samples/ApiDemos/res/layout/picture_in_picture_auto_enter.xml +++ b/samples/ApiDemos/res/layout/picture_in_picture_auto_enter.xml 
@@ -15,18 +15,21 @@  -->    <!-- Demonstrates Picture-In-Picture with auto enter enabled. --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:app="http://schemas.android.com/apk/res-auto"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical">    <!-- layout params would be changed programmatically --> - <ImageView android:id="@+id/image" + <com.example.android.apis.view.FixedAspectRatioImageView + android:id="@+id/image"  android:layout_width="match_parent"  android:layout_height="wrap_content"  android:scaleType="fitXY" - android:src="@drawable/sample_1" /> + android:src="@drawable/sample_1" + app:aspectRatio="16/9" />    <Switch android:id="@+id/source_rect_hint_toggle"  android:layout_width="wrap_content" 
diff --git a/samples/ApiDemos/res/values/attrs.xml b/samples/ApiDemos/res/values/attrs.xml index 1751ae2..f06ebf1 100644 --- a/samples/ApiDemos/res/values/attrs.xml +++ b/samples/ApiDemos/res/values/attrs.xml 
@@ -53,4 +53,8 @@  <attr name="android:label" />  </declare-styleable>  <!-- END_INCLUDE(fragment_arguments) --> + + <declare-styleable name="FixedAspectRatioImageView"> + <attr name="aspectRatio" format="string" /> + </declare-styleable>  </resources> 
diff --git a/samples/ApiDemos/res/values/styles.xml b/samples/ApiDemos/res/values/styles.xml index 2da03f0..6c301ce 100644 --- a/samples/ApiDemos/res/values/styles.xml +++ b/samples/ApiDemos/res/values/styles.xml 
@@ -133,6 +133,8 @@  <style name="Theme.NoActionBar" parent="android:Theme.Material.Light">  <item name="windowActionBar">false</item>  <item name="android:windowNoTitle">true</item> + <!-- toggle this flag to test letterbox behavior when auto-enter-pip from landscape --> + <!--item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item-->  </style>    </resources> 
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/PictureInPictureAutoEnter.java b/samples/ApiDemos/src/com/example/android/apis/app/PictureInPictureAutoEnter.java index 05f4558..57ce6bb 100644 --- a/samples/ApiDemos/src/com/example/android/apis/app/PictureInPictureAutoEnter.java +++ b/samples/ApiDemos/src/com/example/android/apis/app/PictureInPictureAutoEnter.java 
@@ -23,6 +23,7 @@  import android.graphics.Rect;  import android.os.Bundle;  import android.util.Rational; +import android.view.Gravity;  import android.view.View;  import android.view.WindowManager;  import android.widget.CompoundButton; @@ -43,7 +44,6 @@  private View mImageView;  private View mButtonView;  private Switch mSwitchView; - private int mLastOrientation = -1;    @Override  protected void onCreate(Bundle savedInstanceState) { @@ -76,43 +76,52 @@  @Override  public void onConfigurationChanged(Configuration newConfiguration) {  super.onConfigurationChanged(newConfiguration); - if (!isInPictureInPictureMode()) { - updateLayout(newConfiguration); - } + updateLayout(newConfiguration);  }    private void updateLayout(Configuration configuration) { - if (configuration.orientation == mLastOrientation) return; - mLastOrientation = configuration.orientation; - final boolean isLandscape = (mLastOrientation == Configuration.ORIENTATION_LANDSCAPE); - mButtonView.setVisibility(isLandscape ? View.GONE : View.VISIBLE); - mSwitchView.setVisibility(isLandscape ? View.GONE: View.VISIBLE); + final boolean isLandscape = + (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE); + final boolean isPictureInPicture = isInPictureInPictureMode(); + mButtonView.setVisibility((isPictureInPicture || isLandscape) ? View.GONE : View.VISIBLE); + mSwitchView.setVisibility((isPictureInPicture || isLandscape) ? View.GONE: View.VISIBLE);  final LinearLayout.LayoutParams layoutParams; - // Toggle the fullscreen mode as well. - // TODO(b/188001699) switch to use insets controller once the bug is fixed. - final View decorView = getWindow().getDecorView(); - final int systemUiNavigationBarFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - if (isLandscape) { + if (isPictureInPicture) {  layoutParams = new LinearLayout.LayoutParams(  LinearLayout.LayoutParams.MATCH_PARENT,  LinearLayout.LayoutParams.MATCH_PARENT); - getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, - WindowManager.LayoutParams.FLAG_FULLSCREEN); - decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() - | systemUiNavigationBarFlags); + layoutParams.gravity = Gravity.NO_GRAVITY;  } else { - layoutParams = new LinearLayout.LayoutParams( - LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT); - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() - & ~systemUiNavigationBarFlags); + // Toggle the fullscreen mode as well. + // TODO(b/188001699) switch to use insets controller once the bug is fixed. + final View decorView = getWindow().getDecorView(); + final int systemUiNavigationBarFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + if (isLandscape) { + layoutParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.MATCH_PARENT); + layoutParams.gravity = Gravity.CENTER_HORIZONTAL; + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() + | systemUiNavigationBarFlags); + } else { + layoutParams = new LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + layoutParams.gravity = Gravity.NO_GRAVITY; + getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + decorView.setSystemUiVisibility(decorView.getSystemUiVisibility() + & ~systemUiNavigationBarFlags); + }  } + mImageView.addOnLayoutChangeListener(mOnLayoutChangeListener);  mImageView.setLayoutParams(layoutParams);  }    private void updatePictureInPictureParams() { + mImageView.removeOnLayoutChangeListener(mOnLayoutChangeListener);  // do not bother PictureInPictureParams update when it's already in pip mode.  if (isInPictureInPictureMode()) return;  final Rect imageViewRect = new Rect(); 
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/FixedAspectRatioImageView.java b/samples/ApiDemos/src/com/example/android/apis/view/FixedAspectRatioImageView.java new file mode 100644 index 0000000..4c147ec --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/view/FixedAspectRatioImageView.java 
@@ -0,0 +1,64 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.apis.view; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.util.Rational; +import android.widget.ImageView; + +import com.example.android.apis.R; + +/** + * Extended {@link ImageView} that keeps fixed aspect ratio (specified in layout file) when + * one of the dimension is in exact while the other one in wrap_content size mode. + */ +public class FixedAspectRatioImageView extends ImageView { + private final Rational mAspectRatio; + + public FixedAspectRatioImageView(Context context, AttributeSet attrs) { + super(context, attrs); + final TypedArray a = context.getTheme().obtainStyledAttributes(attrs, + R.styleable.FixedAspectRatioImageView, 0, 0); + try { + mAspectRatio = Rational.parseRational( + a.getString(R.styleable.FixedAspectRatioImageView_aspectRatio)); + } finally { + a.recycle(); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + final int width, height; + if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY + && MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) { + width = MeasureSpec.getSize(widthMeasureSpec); + height = MeasureSpec.getSize(heightMeasureSpec); + } else if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) { + width = MeasureSpec.getSize(widthMeasureSpec); + height = (int) (width / mAspectRatio.floatValue()); + } else { + height = MeasureSpec.getSize(heightMeasureSpec); + width = (int) (height * mAspectRatio.floatValue()); + } + android.util.Log.d("DebugMe", "onMeasure w=" + width + " h=" + height); + setMeasuredDimension(width, height); + } +} \ No newline at end of file